package com.shop.cereshop.admin.aspect;

import com.shop.cereshop.admin.dao.history.CereWebHistoryDAO;
import com.shop.cereshop.admin.dao.user.CerePlatformUserDAO;
import com.shop.cereshop.admin.param.buyer.BuyerGetUsersParam;
import com.shop.cereshop.admin.redis.service.UserRedisService;
import com.shop.cereshop.admin.service.history.CereWebHistoryService;
import com.shop.cereshop.commons.domain.history.CereWebHistory;
import com.shop.cereshop.commons.domain.user.CerePlatformUser;
import com.shop.cereshop.commons.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@RequiredArgsConstructor
public class OperationLogAspect {

    // 注入日志DAO（或Service），用于保存日志
    @Autowired
    private final CereWebHistoryDAO cereWebHistoryDAO;
    @Autowired
    private UserRedisService userRedisService;
    @Autowired
    private CerePlatformUserDAO cerePlatformUserDAO;
    // 切入点：拦截所有被@OperationLog注解标记的方法
    @Pointcut("@annotation(com.shop.cereshop.admin.aspect.OperationLog)")
    public void logPointCut() {}

    // 环绕通知：在方法执行前后记录日志
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 1. 初始化日志对象
        CereWebHistory cereWebHistory = new CereWebHistory();
        cereWebHistory.setWebActionTime(LocalDateTime.now()); // 操作时间

        // 3. 获取注解信息（操作行为、操作类型）
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        OperationLog operationLogAnnotation = method.getAnnotation(OperationLog.class);
     //   cereWebHistory.setWebAction(operationLogAnnotation.operation()); // 操作行为
        cereWebHistory.setWebActionType(operationLogAnnotation.operationType()); // 操作类型

        // 4. 获取当前登录用户信息（ID、昵称、手机号）
        // 注意：需根据项目实际的登录上下文获取（如SpringSecurity的SecurityContext、Shiro的Subject等）
        CerePlatformUser currentUser = getCurrentUser();
        if (currentUser != null) {
            cereWebHistory.setWebPlatformUserId(currentUser.getPlatformUserId());
            cereWebHistory.setWebName(currentUser.getName());
            cereWebHistory.setWebPhone(currentUser.getPhone());
        }
        // 5.1 获取方法参数名和参数值
        String[] paramNames = signature.getParameterNames(); // 参数名数组：["param", "request"]
        Object[] paramValues = joinPoint.getArgs(); // 参数值数组：[BuyerGetUsersParam对象, HttpServletRequest对象]

        // 5.2 构建参数映射（参数名 -> 参数值）
        Map<String, Object> paramMap = new HashMap<>();
        for (int i = 0; i < paramNames.length; i++) {
            paramMap.put(paramNames[i], paramValues[i]);
        }

        // 5.3 从param参数中获取buyerUserId（被禁用的用户ID）
        Long buyerUserId = null;
        if (paramMap.containsKey("param") && paramMap.get("param") instanceof BuyerGetUsersParam) {
            BuyerGetUsersParam param = (BuyerGetUsersParam) paramMap.get("param");
            buyerUserId = param.getBuyerUserId(); // 拿到被禁用用户的ID
        }
        String operationTemplate = operationLogAnnotation.operation(); // 获取模板："{operateUserNickname}禁用了id为{buyerUserId}的用户"
        // 6. 替换操作描述模板中的占位符
        String actualOperation = operationTemplate
                .replace("{buyerUserId}", buyerUserId != null ? buyerUserId.toString() : "未知ID");
        cereWebHistory.setWebAction(actualOperation); // 设置最终的操作描述
        Object result;
        try {
            // 5. 执行目标方法
            result = joinPoint.proceed();
            // 6. 方法执行成功，标记结果为"成功"
            cereWebHistory.setWebActionResult("成功");
        } catch (Exception e) {
            // 7. 方法执行失败，标记结果为"失败"并记录错误信息
            cereWebHistory.setWebActionResult("失败");

            throw e; // 继续抛出异常，不影响原有业务逻辑
        } finally {
            // 8. 保存日志到数据库
            cereWebHistoryDAO.insert(cereWebHistory);
        }
        return result;
    }

    // 获取当前登录用户（需根据项目实际实现）
    private CerePlatformUser getCurrentUser() {

        // 1. 从请求头中获取 token（假设前端将 token 放在 Authorization 头中，格式：Bearer xxx）
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return null; // 非web环境，无请求信息
        }
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("Authorization-admin");
        // 3. 如果 token 为空，直接返回 null
        if (StringUtils.isBlank(token)) {
            return null;
        }
        //查询token信息
        Long userId = userRedisService.getBuyerUserIdByToken(token);
        CerePlatformUser cerePlatformUser = cerePlatformUserDAO.selectByPrimaryKey(userId);

        return cerePlatformUser; // 实际项目中替换为真实逻辑
    }
}
